package com.gpnu7_412.yanzhi.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.gpnu7_412.yanzhi.dto.ConciseUserDto;
import com.gpnu7_412.yanzhi.entity.Interest;
import com.gpnu7_412.yanzhi.entity.User;
import com.gpnu7_412.yanzhi.entity.UserDetail;
import com.gpnu7_412.yanzhi.dto.UserMessageDto;
import com.gpnu7_412.yanzhi.entity.UserHanding;
import com.gpnu7_412.yanzhi.exception.custom.DataInconsistencyException;
import com.gpnu7_412.yanzhi.exception.custom.DataNotFoundException;
import com.gpnu7_412.yanzhi.exception.custom.RequestDataException;
import com.gpnu7_412.yanzhi.exception.custom.SQLExecuteException;
import com.gpnu7_412.yanzhi.mapper.*;
import com.gpnu7_412.yanzhi.service.UserService;
import com.gpnu7_412.yanzhi.util.AliOssUtil;
import com.gpnu7_412.yanzhi.util.JwtUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.sql.Timestamp;
import java.util.*;

/**
 * @author ZZH
 */
@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserMapper userMapper;
    @Autowired
    private UserDetailMapper userDetailMapper;
    @Autowired
    private CommentMapper commentMapper;
    @Autowired
    private DynamicMapper dynamicMapper;
    @Autowired
    private InterestMapper interestMapper;
    @Autowired
    private NoticeMapper noticeMapper;
    @Autowired
    private UserHandingMapper userHandingMapper;

    /**
     * 用户注册
     * @param user 用户对象
     * @return boolean
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean register(User user) {
        if (user == null) {
            return false;
        }
        // 查看该邮箱是否已被注册
        User selectUser = userMapper.selectByEmail(user.getEmail());
        if (selectUser != null) {
            throw new DataInconsistencyException("该邮箱已被注册");
        }
        // 添加用户基本信息
        if (userMapper.insert(user) != 1) {
            throw new SQLExecuteException("注册失败，请重试或联系管理员");
        }
        userDetailMapper.delete(user.getUserId());
        if (userDetailMapper.insert(user.getUserId()) != 1) {
            throw new SQLExecuteException("注册失败，请重试或联系管理员");
        }
        return true;
    }

    /**
     * 用户使用密码登录
     * @param email 登录邮箱
     * @param password 登录密码
     * @return 用户对象
     */
    @Override
    public User loginByPassword(String email, String password) {
        if (email == null || password == null) {
            return null;
        }
        User user = userMapper.selectByEmail(email);
        if (user == null) {
            throw new DataNotFoundException("账号不存在");
        }
        if (!user.getPassword().equals(password)) {
            throw new DataInconsistencyException("密码错误");
        }
        return user;
    }

    /**
     * 用户使用验证码方式登录
     * @param email 用户邮箱
     * @return 用户对象
     */
    @Override
    public User loginByVerification(String email) {
        if (email == null) {
            return null;
        }
        User user = userMapper.selectByEmail(email);
        if (user == null) {
            throw new DataNotFoundException("该邮箱未注册");
        }
        return user;
    }

    /**
     * 用户忘记密码
     * @param email 用户邮箱
     * @param newPassword 新密码
     * @return boolean
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean forgetPassword(String email, String newPassword) {
        if (email == null || newPassword == null) {
            return false;
        }
        User user = userMapper.selectByEmail(email);
        if (user == null) {
            throw new DataNotFoundException("该用户不存在");
        }
        if (userMapper.updatePassword(user.getUserId(), newPassword) != 1) {
            throw new SQLExecuteException("密码修改失败，请重试或联系管理员");
        }
        return true;
    }

    /**
     * 获取用户所有信息
     * @param userId 用户ID
     * @return 用户信息对象
     */
    @Override
    public UserMessageDto getUserMessageById(Integer userId) {
        if (userId == null) {
            return null;
        }
        User user = userMapper.selectById(userId);
        UserDetail userDetail = userDetailMapper.selectByUserId(userId);
        if (user == null || userDetail == null) {
            throw new DataNotFoundException("数据获取失败，请重试或联系管理员");
        }
        return new UserMessageDto(user, userDetail);
    }

    /**
     * 分页查询所有用户
     *
     * @param pageNum  查询页
     * @param pageSize 页面大小
     * @return 分页查询结果
     */
    @Override
    public PageInfo<ConciseUserDto> getAllUsersByPage(Integer pageNum, Integer pageSize) {
        PageHelper.startPage(pageNum, pageSize);
        List<ConciseUserDto> conciseUserDtos = userMapper.selectAllUsers();
        PageInfo<ConciseUserDto> pageInfo = new PageInfo<>(conciseUserDtos, 5);
        return pageInfo;
    }

    /**
     * 根据条件分页查询用户
     *
     * @param pageNum  查询页
     * @param pageSize 页面大小
     * @param user     用户信息
     * @return 简洁用户对象列表
     */
    @Override
    public PageInfo<User> getUsersByCondition(Integer pageNum, Integer pageSize, User user) {
        Integer userId = user.getUserId();
        String userName;
        String email;
        if (user.getUserName() == null || user.getUserName().isEmpty()) {
            userName = null;
        } else {
            userName = user.getUserName() + "%";
        }
        if (user.getEmail() == null || user.getEmail().isEmpty()) {
            email = null;
        } else {
            email = user.getEmail() + "%";
        }
        PageHelper.startPage(pageNum, pageSize);
        List<User> userList = userMapper.selectByCondition(userId, userName, email);
        PageInfo<User> pageInfo = new PageInfo<>(userList, 5);
        return pageInfo;
    }

    /**
     * 修改用户基本信息
     * @param userMessageDto 用户信息
     * @return boolean
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateBaseMessage(UserMessageDto userMessageDto) {
        if (userMessageDto == null) {
            return false;
        }
        Integer updateNum = userMapper.updateBaseMessage(userMessageDto);
        if (updateNum == 1 || updateNum == 2) {
            return true;
        }
        throw new SQLExecuteException("信息修改失败，请重试");
    }

    /**
     * 修改当前登录用户头像
     *
     * @param avatarFile 头像文件
     * @param userId 用户ID
     * @return boolean
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateAvatar(MultipartFile avatarFile, Integer userId) {
        if (avatarFile == null || userId == null) {
            return false;
        }
        User user = userMapper.selectById(userId);
        if (user == null) {
            throw new DataNotFoundException("用户不存在");
        }
        Random rand = new Random();
        String avatarUrl;
        try {
            AliOssUtil.deleteFile(user.getAvatar());
            String extension = Objects.requireNonNull(avatarFile.getOriginalFilename()).substring(avatarFile.getOriginalFilename().lastIndexOf("."));
            System.out.println(extension);
            avatarUrl = AliOssUtil.uploadFile(userId + "-" + rand.nextInt(100) + extension, avatarFile.getInputStream());
            System.out.println(avatarUrl);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        if (userMapper.updateAvatar(userId, avatarUrl) != 1) {
            throw new SQLExecuteException("修改失败，请重试或联系管理员");
        }
        return true;
    }

    /**
     * 用户修改密码
     * @param userId 用户ID
     * @param oldPassword 旧密码
     * @param newPassword 新密码
     * @return boolean
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updatePassword(Integer userId, String oldPassword, String newPassword) {
        if(userId <= 0) {
            throw new RequestDataException("用户id获取失败，请重试");
        }
        User user = userMapper.selectById(userId);
        if (user == null) {
            throw new DataNotFoundException("用户不存在");
        }
        //先匹配旧密码
        if (user.getPassword() == null) {
            throw new SQLExecuteException("密码获取错误，请重试");
        }
        if (!user.getPassword().equals(oldPassword)) {
            throw new DataInconsistencyException("密码验证错误");
        }
        //新旧密码比较
        if (user.getPassword().equals(newPassword)) {
            throw new DataInconsistencyException("新密码与旧密码相同，请重试");
        }
        //匹配成功，密码替换
        if (userMapper.updatePassword(userId,newPassword) != 1) {
            throw new SQLExecuteException("密码修改失败，请重试或联系管理员");
        }
        return true;
    }

    /**
     * 用户修改邮箱
     * @param userId 用户ID
     * @param newEmail 新邮箱
     * @return boolean
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateEmail(Integer userId, String newEmail) {
        if (userId == null || newEmail == null) {
            return false;
        }
        User selectUser = userMapper.selectById(userId);
        if (selectUser == null) {
            throw new DataNotFoundException("查无用户");
        }
        if (selectUser.getEmail().equals(newEmail)) {
            throw new DataInconsistencyException("新邮箱与旧邮箱相同，请重试");
        }
        if (userMapper.selectByEmail(newEmail) != null) {
            throw new DataInconsistencyException("该邮箱已被注册");
        }
        if (userMapper.updateEmail(userId, newEmail) != 1) {
            throw new SQLExecuteException("邮箱修改错误，请重试或联系管理员");
        }
        return true;
    }

    /**
     * 用户关注
     * @param userId 用户ID
     * @param likeUserId 被关注用户ID
     * @return boolean
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean attention(Integer userId, Integer likeUserId) {
        if (userId == null || likeUserId == null || userId.equals(likeUserId)) {
            return false;
        }
        Interest interest = new Interest(userId, likeUserId, new Timestamp(System.currentTimeMillis()));
        if (interestMapper.insert(interest) != 1) {
            throw new SQLExecuteException("关注失败，请重试或联系管理员");
        }
        if (userDetailMapper.updateFansNumByUserId(likeUserId, 1) != 1) {
            throw new SQLExecuteException("关注失败，请重试或联系管理员");
        }
        return true;
    }

    /**
     * 用户取消关注
     * @param userId 用户ID
     * @param likeUserId 被取关用户ID
     * @return boolean
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean unfollow(Integer userId, Integer likeUserId) {
        if (userId == null || likeUserId == null || userId.equals(likeUserId)) {
            return false;
        }
        if (interestMapper.delete(userId, likeUserId) != 1) {
            throw new SQLExecuteException("取关失败，请重试或联系管理员");
        }
        if (userDetailMapper.updateFansNumByUserId(likeUserId, -1) != 1) {
            throw new SQLExecuteException("取关失败，请重试或联系管理员");
        }
        return true;
    }

    /**
     * 用户举报
     * @param userHanding 用户举报对象
     * @return boolean
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean report(UserHanding userHanding) {
        if (userHanding == null) {
            return false;
        }
        if (userHandingMapper.insert(userHanding) != 1) {
            throw new SQLExecuteException("举报失败，请重试或联系管理员");
        }
        return true;
    }

    /**
     * 用户注销
     * @param userId 用户ID
     * @return boolean
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteUser(Integer userId) {
        if (userId == null) {
            throw new RequestDataException("用户id获取失败，请重试");
        }
        // 逐个表删除，从评论表(comment)开始
        commentMapper.deleteCommentByUserId(userId);
        // 删除动态表(dynamic)
        dynamicMapper.deleteDynamicByUserId(userId);
        // 确保用户粉丝数的一致性
        List<User> userList = interestMapper.selectMyInterestList(userId);
        for (User user : userList) {
            userDetailMapper.updateFansNumByUserId(user.getUserId(), -1);
        }
        // 删除关注表(删两次，我关注的，以及谁关注了我，interest)
        interestMapper.deleteMyInterestByUserId(userId);
        interestMapper.deleteInterestMeByUserId(userId);
        // 删除通知表
        noticeMapper.deleteNoticeByUserId(userId);
        // 删除用户详细表
        Integer userDetailDelete = userDetailMapper.delete(userId);
        //删除用户
        Integer userDelete = userMapper.deleteById(userId);
        if (userDelete != 1 || userDetailDelete != 1) {
            throw new SQLExecuteException("用户注销失败，请重试或联系管理员");
        }
        return true;
    }

    /**
     * 生成 jwt 令牌
     * @param user 用户信息
     * @return jwt令牌
     */
    @Override
    public String getJwtToken(User user) {
        if (user == null) {
            return null;
        }
        // 封装数据
        Map<String, Object> claims = new HashMap<>(4);
        claims.put("userId", user.getUserId());
//        claims.put("userName", user.getUserName());
//        claims.put("avatar", user.getAvatar());
        claims.put("permission", user.getPermission());
        // 生成 jwt 令牌
        return JwtUtils.generateJwtToken(claims);
    }

    /**
     * 根据用户名模糊搜索
     * @param userName 用户名
     * @return 用户列表
     */
    @Override
    public List<ConciseUserDto> getConciseUsersByName(String userName) {
        if (userName == null) {
            return null;
        }
        userName = "%" + userName + "%";
        return userMapper.selectConciseUsersByName(userName);
    }

    /**
     * 根据用户邮箱前缀模糊查找用户
     * @param email 邮箱前缀
     * @return 用户对象列表
     */
    @Override
    public List<ConciseUserDto> getConciseUsersByEmail(String email) {
        if (email == null) {
            return null;
        }
        email = email + "%";
        return userMapper.selectConciseUsersByEmail(email);
    }

    /**
     * 根据获取用户基本信息
     * @param userId 用户ID
     * @return 基本用户信息
     */
    @Override
    public User selectUserById(Integer userId) {
        if(userId == null || userId <= 0) {
            throw new RequestDataException("用户Id获取异常，可能是id格式问题");
        }
        User user = userMapper.selectById(userId);
        if (user == null) {
            throw new SQLExecuteException("查询操作异常，请重试");
        }
        return user;
    }

    /**
     * 根据用户名搜索用户
     * @param userName 用户名
     * @return 用户列表
     */
    @Override
    public List<User> selectUserByUserName(String userName) {
//        if (userName == null) {
//            throw new RequestDataException("参数不允许为空");
//        }
//        List<User> userList = userMapper.selectUserByUserName("%" + userName + "%");
//        if (userList == null) {
//            throw new SQLExecuteException("查询执行失败");
//        }
//        return userList;
        return null;
    }

    /**
     * 根据邮箱搜索
     * @param email 邮箱
     * @return 用户列表
     */
    @Override
    public List<User> selectUserByEmail(String email) {
//        if (email == null) {
//            throw new RequestDataException("参数不允许为空");
//        }
//        List<User> userList = userMapper.selectUserByEmail(email + "%");
//        if (userList == null) {
//            throw new SQLExecuteException("查询执行失败");
//        }
//        return userList;
        return null;
    }

}
